package indexv1

import (
	"bytes"
	"context"
	"encoding/base64"
	"time"

	"lingc/config"
	"lingc/services"
	"lingc/utils" // 导入 common 包

	"github.com/dchest/captcha"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
)

// GenerateCaptcha 生成验证码
func GenerateCaptcha(c *gin.Context) {
	// 生成一个新的验证码 ID
	captchaID := captcha.NewLen(4)

	// 将生成的验证码图片写入缓冲区
	var buf bytes.Buffer
	err := captcha.WriteImage(&buf, captchaID, 150, 70)
	if err != nil {
		utils.SendJSONResponse(c, utils.BadRequestCode, gin.H{"msg": "Failed to generate captcha image"}) // 替换为 common 包中的函数
		return
	}

	// 将缓冲区中的图片数据编码为Base64
	captchaImageBase64 := base64.StdEncoding.EncodeToString(buf.Bytes())

	// log.Println("Generated captcha ID:", captchaID)
	// log.Println("Generated captcha base64:", captchaImageBase64)
	// utils.SendJSONResponse(c, utils.SuccessCode, gin.H{"msg": "Login successful", "token": captchaImageBase64})
	// 返回 captchaID 和 base64 编码的图片数据给前端
	utils.SendJSONResponse(c, utils.SuccessCode, gin.H{"captcha_id": captchaID, "captcha_image": "data:image/png;base64," + captchaImageBase64}) // 替换为 common 包中的函数
}

// Login 用户登录
func MemberLogin(c *gin.Context) {
	// 前端需要先调用 GenerateCaptcha 接口获取 CaptchaID
	var loginData struct {
		Username  string `json:"username" binding:"required"`
		Password  string `json:"password" binding:"required"`
		LoginType string `json:"login_type" binding:"required"`
	}
	// 获取客户端IP
	var ip = utils.GetClientIP(c)
	if err := c.ShouldBindJSON(&loginData); err != nil {
		utils.SendJSONResponse(c, utils.ErrorCode, gin.H{"msg": err.Error()})
		return
	}
	// 验证验证码
	// if !captcha.VerifyString(loginData.CaptchaID, loginData.Captcha) {
	// 	utils.SendJSONResponse(c, utils.ErrorCode, gin.H{"msg": "Invalid captcha"})
	// 	return
	// }

	user, err := services.NewMemberService(utils.MysqlClient).Login(loginData.Username, loginData.Password, ip, loginData.LoginType)
	if err != nil {
		utils.SendJSONResponse(c, utils.ErrorCode, gin.H{"msg": err.Error()})
		return
	}
	// log.Println("user:", user)

	// 创建token
	expirationTime := time.Now().Add(config.AdminTokenTime * time.Minute)
	/**
	ID       uint   `json:"id"`
	Username string `json:"username"`
	Avatar   string `json:"avatar"`
	Realname string `json:"realname"`
	*/
	claims := utils.Claims{
		ID:       user.ID,
		Username: loginData.Username,
		Avatar:   user.HeadImg,
		Nickame:  user.NickName,
		Type:     "member",
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: expirationTime.Unix(),
		},
	}
	tokenString, err := utils.GenerateToken(claims, config.AdminTokenTime)
	if err != nil {
		utils.SendJSONResponse(c, utils.ErrorCode, gin.H{"msg": "Failed to generate token"})
		return
	}
	// 将token存储到Redis中

	utils.SetRedis(utils.GenerateMD5("user_token_"+loginData.Username), tokenString, config.AdminTokenTime)
	RefreshexpirationTime := time.Now().Add(config.RefreshTokenTime * time.Minute)
	RefreshtokenString, err := utils.GenerateToken(claims, config.RefreshTokenTime)
	if err != nil {
		utils.SendJSONResponse(c, utils.ErrorCode, gin.H{"msg": "Failed to generate RefreshToken"})
		return
	}
	utils.SetRedis(utils.GenerateMD5("user_RefreshToken_"+loginData.Username), RefreshtokenString, config.RefreshTokenTime)
	// 测试通知
	// notifymessage := MyTextMessage{
	// 	ID:       "11dhd378shjhfjdhsj",
	// 	Content:  "{\"type\":\"MESSAGE\",\"title\":\"测试通知\",\"url\":\"https://www.baidu.com\"}",
	// 	UserID:   "1",
	// 	UserType: "admin",
	// }
	// SendToNotify(notifymessage)
	//发送群组消息
	// SendToGroup(1)
	// 设置刷新token过期时间
	expires := RefreshexpirationTime.Unix()
	// ... existing code for user authentication ...
	utils.SendJSONResponse(c, utils.SuccessCode, gin.H{"accessToken": tokenString, "expires": expires, "refreshToken": RefreshtokenString})
}

// 刷新Token
func MemberRefreshtoken(c *gin.Context) {
	// 刷新token
	var RefreshData struct {
		RefreshToken string `json:"refreshToken" binding:"required"`
	}
	if err := c.ShouldBindJSON(&RefreshData); err != nil {
		utils.SendJSONResponse(c, utils.ErrorCode, gin.H{"msg": err.Error()})
		return
	}
	user_token := utils.ValidateToken(RefreshData.RefreshToken)
	// 验证token
	if user_token == nil {
		utils.SendJSONResponse(c, utils.ErrorToken, gin.H{"msg": "无效的token"})
		c.Abort()
		return
	}

	//获取缓存token
	redis_token := utils.GetRedis(utils.GenerateMD5("user_RefreshToken_" + user_token.Username))
	if redis_token == "" {
		utils.SendJSONResponse(c, utils.ErrorToken, gin.H{"msg": "无效的token", "code": 1})
		c.Abort()
		return
	}
	if RefreshData.RefreshToken != redis_token {
		utils.SendJSONResponse(c, utils.ErrorToken, gin.H{"msg": "无效的token", "code": 2})
		c.Abort()
		return
	}
	user_info, err := services.NewMemberService(utils.MysqlClient).GetMemberById(user_token.ID)
	if err != nil {
		utils.SendJSONResponse(c, utils.ErrorCode, gin.H{"msg": err.Error()})
		return
	}
	// 创建token
	expirationTime := time.Now().Add(config.AdminTokenTime * time.Minute)
	/**
	ID       uint   `json:"id"`
	Username string `json:"username"`
	Avatar   string `json:"avatar"`
	Realname string `json:"realname"`
	*/
	claims := utils.Claims{
		ID:       user_info.ID,
		Username: user_info.Username,
		Avatar:   user_info.HeadImg,
		Nickame:  user_info.NickName,
		Type:     "member",
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: expirationTime.Unix(),
		},
	}
	tokenString, err := utils.GenerateToken(claims, config.AdminTokenTime)
	if err != nil {
		utils.SendJSONResponse(c, utils.ErrorCode, gin.H{"msg": "Failed to generate token"})
		return
	}
	// 将token存储到Redis中
	utils.SetRedis(utils.GenerateMD5("user_token_"+user_info.Username), tokenString, config.AdminTokenTime)
	RefreshexpirationTime := time.Now().Add(config.RefreshTokenTime * time.Minute)
	RefreshtokenString, err := utils.GenerateToken(claims, config.RefreshTokenTime)
	if err != nil {
		utils.SendJSONResponse(c, utils.ErrorCode, gin.H{"msg": "Failed to generate RefreshToken"})
		return
	}
	utils.SetRedis(utils.GenerateMD5("user_RefreshToken_"+user_info.Username), RefreshtokenString, config.RefreshTokenTime)
	// 设置刷新token过期时间
	expires := RefreshexpirationTime.Unix()
	// ... existing code for user authentication ...
	utils.SendJSONResponse(c, utils.SuccessCode, gin.H{"accessToken": tokenString, "expires": expires, "refreshToken": RefreshtokenString})
}

// Logout 用户登出
func MemberLogout(c *gin.Context) {
	userInterface, exists := c.Get("user")
	if !exists {
		utils.SendJSONResponse(c, utils.ErrorToken, gin.H{"msg": "用户未找到"})
		return
	}
	user, ok := userInterface.(*utils.Claims) // 假设 utils.User 是 user 的类型
	if !ok {
		utils.SendJSONResponse(c, utils.ErrorToken, gin.H{"msg": "用户类型失败"})
		return
	}

	key := utils.GenerateMD5("user_token_" + user.Username)
	utils.RedisClient.Del(context.Background(), key)
	refreshKey := utils.GenerateMD5("user_RefreshToken_" + user.Username)
	utils.RedisClient.Del(context.Background(), refreshKey)
	utils.SendJSONResponse(c, utils.SuccessCode, gin.H{"msg": "Logout successful"}) // 替换为 common 包中的函数
}

func GetMemberInfo(c *gin.Context) {
	// 获取 user 数据
	userInterface, exists := c.Get("user")
	if !exists {
		utils.SendJSONResponse(c, utils.ErrorToken, gin.H{"msg": "用户未找到"})
		return
	}
	user, ok := userInterface.(*utils.Claims) // 假设 utils.User 是 user 的类型
	if !ok {
		utils.SendJSONResponse(c, utils.ErrorToken, gin.H{"msg": "用户类型失败"})
		return
	}
	user_info, err := services.NewMemberService(utils.MysqlClient).GetMemberById(user.ID)
	if err != nil {
		utils.SendJSONResponse(c, utils.ErrorCode, gin.H{"msg": err.Error()})
		return
	}
	user_data := gin.H{
		"user_id":         user_info.ID,
		"username":        user_info.Username,
		"nick_name":       user_info.NickName,
		"head_img":        user_info.HeadImg,
		"phone":           user_info.Phone,
		"email":           user_info.Email,
		"gender":          user_info.Grender,
		"balance":         user_info.Balance,
		"integral":        user_info.Integral,
		"description":     user_info.Description,
		"popularize_code": user_info.PopularizeCode,
		"birthday":        user_info.Birthday,
	}
	// 替换为 common 包中的函数，并返回 user 数据
	utils.SendJSONResponse(c, utils.SuccessCode, user_data)
}
